using LiteDB;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DidaManager.Log;
using Newtonsoft.Json.Linq;
using System.Text;

namespace LiteDb
{
    /// <summary>
    /// 多数据库管理器 - 专注于设备数据库管理
    /// </summary>
    public class MultiDbManager : IDisposable
    {
        private readonly DeviceDbConnectionManager _deviceDbManager;
        private readonly MultiDbConfiguration _config;

        public MultiDbManager(MultiDbConfiguration? config = null)
        {
            _config = config ?? new MultiDbConfiguration();
            _deviceDbManager = new DeviceDbConnectionManager(_config);
            
            LogManager.Info($"多数据库管理器已初始化，数据库目录: {_config.BasePath}");
        }

        /// <summary>
        /// 根据设备ID获取对应的CefSharpServer
        /// </summary>
        public CefSharpServer GetDeviceCefSharpServer(int deviceId)
        {
            return _deviceDbManager.GetDeviceCefSharpServer(deviceId);
        }

        /// <summary>
        /// 强制关闭设备数据库连接
        /// </summary>
        public void ForceCloseDeviceDatabase(int deviceId)
        {
            _deviceDbManager.ForceCloseDeviceDatabase(deviceId);
        }

        /// <summary>
        /// 获取设备对应的分组ID
        /// </summary>
        public int GetGroupIdByDeviceId(int deviceId)
        {
            return _deviceDbManager.GetGroupIdByDeviceId(deviceId);
        }

        /// <summary>
        /// 获取设备数据库文件路径
        /// </summary>
        public string GetDeviceDatabasePath(int deviceId, int groupId)
        {
            return _deviceDbManager.GetDeviceDatabasePath(deviceId, groupId);
        }

        /// <summary>
        /// 安全文件复制
        /// </summary>
        public bool SafeFileCopy(string sourcePath, string destPath, int maxRetries = 3, int retryDelayMs = 500)
        {
            return _deviceDbManager.SafeFileCopy(sourcePath, destPath, maxRetries, retryDelayMs);
        }

        /// <summary>
        /// 删除设备数据库
        /// </summary>
        public bool DeleteDeviceDatabase(int deviceId,int groupId)
        {
            return _deviceDbManager.DeleteDeviceDatabase(deviceId, groupId);
        }

        /// <summary>
        /// 删除整个分组的数据库文件夹
        /// </summary>
        public object DeleteGroupDatabases(object param)
        {
            try
            {
                var groupId = Convert.ToInt32(param);
                var groupFolder = Path.Combine(_config.BasePath, string.Format(_config.GroupFolderTemplate, groupId));
                
                LogManager.Info($"准备删除分组文件夹: {groupFolder}");
                
                if (Directory.Exists(groupFolder))
                {
                    // 先关闭该分组下所有设备的连接
                    var deviceFiles = Directory.GetFiles(groupFolder, "device_*.db");
                    var deletedCount = 0;
                    
                    LogManager.Info($"分组 {groupId} 中找到 {deviceFiles.Length} 个设备数据库文件");
                    
                    foreach (var deviceFile in deviceFiles)
                    {
                        try
                        {
                            // 从文件名中提取设备ID
                            var fileName = Path.GetFileNameWithoutExtension(deviceFile);
                            if (fileName.StartsWith("device_") && int.TryParse(fileName.Substring(7), out var deviceId))
                            {
                                // 关闭连接
                                if (_deviceDbManager.DeleteDeviceDatabase(deviceId, groupId))
                                {
                                    deletedCount++;
                                    LogManager.Debug($"已关闭设备 {deviceId} 的数据库连接");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogManager.Warn($"关闭设备数据库连接时出现问题: {ex.Message}");
                        }
                    }
                    
                    // 删除整个分组文件夹
                    Directory.Delete(groupFolder, true);
                    
                    LogManager.Info($"已删除分组文件夹: {groupFolder}，包含 {deletedCount} 个设备数据库");
                    
                    return ApiResponse.Success(new { 
                        groupId = groupId,
                        deletedDeviceCount = deletedCount,
                        groupFolder = groupFolder
                    }, $"删除分组成功，共删除 {deletedCount} 个设备数据库");
                }
                else
                {
                    LogManager.Warn($"分组文件夹不存在: {groupFolder}");
                    return ApiResponse.Success(new { 
                        groupId = groupId,
                        deletedDeviceCount = 0
                    }, "分组文件夹不存在，无需删除");
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"删除分组数据库失败: {ex.Message}", ex);
                return ApiResponse.Fail($"删除分组数据库失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取数据库统计信息
        /// </summary>
        public object GetDatabaseStats()
        {
            try
            {
                var databaseFiles = _deviceDbManager.GetAllDeviceDatabaseFiles();
                
                // 按分组统计
                var groupStats = new Dictionary<string, object>();
                foreach (var file in databaseFiles)
                {
                    var groupFolder = Path.GetFileName(Path.GetDirectoryName(file));
                    if(groupFolder == null)
                    {
                        continue;
                    }
                    if (groupStats.ContainsKey(groupFolder))
                    {
                        groupStats[groupFolder] = new
                        {
                            groupFolder = groupFolder,
                            deviceCount = 0,
                            totalSize = 0L,
                            devices = new List<object>()
                        };
                    }
                    
                    var stats = (dynamic)groupStats[groupFolder];
                    var fileInfo = new FileInfo(file);
                    stats.deviceCount++;
                    stats.totalSize += fileInfo.Length;
                    ((List<object>)stats.devices).Add(new
                    {
                        fileName = Path.GetFileName(file),
                        size = fileInfo.Length,
                        lastModified = fileInfo.LastWriteTime
                    });
                }
                
                return ApiResponse.Success(new { 
                    basePath = _config.BasePath,
                    totalDeviceCount = databaseFiles.Count,
                    groupCount = groupStats.Count,
                    groups = groupStats.Values.ToList()
                });
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"获取失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 导出设备数据库文件
        /// </summary>
        public object ExportGroupDevice(object param,string groupDeviceJson)
        {
            try
            {
                // 获取分组设备id和导出文件夹路径
                if (param == null)
                {
                    return ApiResponse.Fail("参数不能为空");
                }
                var jsonParam = JObject.Parse(param.ToString() ?? "");
                var groupId = jsonParam["groupDeviceId"]?.ToString();
                var exportFolder = jsonParam["exportFolder"]?.ToString();
                var exportFile = jsonParam["exportFileName"]?.ToString();
                var deviceId = jsonParam["deviceId"]?.ToString();

                if (string.IsNullOrEmpty(groupId) || string.IsNullOrEmpty(exportFolder) || string.IsNullOrEmpty(exportFile) || string.IsNullOrEmpty(deviceId))
                {
                    return ApiResponse.Fail("参数不能为空");
                }

                
                var groupFolder = Path.Combine(_config.BasePath, string.Format(_config.GroupFolderTemplate, groupId));
                var deviceName = string.Format(_config.DeviceDbTemplate, deviceId);
                var exportFileName = exportFile+".db";
                var dbPath = groupFolder + "\\" +deviceName;
                // 检查dbPath是否存在
                if (!File.Exists(dbPath))
                {
                    return ApiResponse.Fail("设备数据库文件不存在");
                }
                // 检查exportFolder是否存在
                exportFolder += "\\" + exportFile;// 需要再创建一个文件夹，用于存储设备数据库文件
                if (!Directory.Exists(exportFolder))
                {
                    Directory.CreateDirectory(exportFolder);// 创建文件夹
                }
                
                // 获取分组设备的文件存储路径，把分组设备拷贝到导出文件夹，并把文件命名为exportFileName
                var exportFilePath = Path.Combine(exportFolder, exportFileName);
                // FIXME 需要导出设备配置文件(否则无法还原)
                File.Copy(dbPath, exportFilePath, true);
                // 需要相同目录下创建一个json文件，文件名称为和
                string dbConfigPath = exportFile+".json";
                string dbConfigFilePath = Path.Combine(exportFolder, dbConfigPath);
                // 文件不存在则创建
                if (!File.Exists(dbConfigFilePath))
                {
                    File.WriteAllText(dbConfigFilePath, groupDeviceJson, new UTF8Encoding(false));
                }
                return ApiResponse.Success("导出成功");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"导出设备数据库文件失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 导入设备数据库文件
        /// </summary>
        public object ImportGroupDevice(object param, int deviceId)
        {
            // FIXME 需要获取设备配置文件(否则无法还原)
            try
            {
                // 获取分组设备id和导出文件夹路径
                if (param == null)
                {
                    return ApiResponse.Fail("参数不能为空");
                }
                var jsonParam = JObject.Parse(param.ToString() ?? "");
                var groupId = jsonParam["groupDeviceId"]?.ToString();
                var importFolder = jsonParam["importFolder"]?.ToString();

                if (string.IsNullOrEmpty(groupId) || string.IsNullOrEmpty(importFolder))
                {
                    return ApiResponse.Fail("参数不能为空");
                }

                var groupFolder = Path.Combine(_config.BasePath, string.Format(_config.GroupFolderTemplate, groupId));
                var deviceName = string.Format(_config.DeviceDbTemplate, deviceId);
                var dbNewPath = groupFolder + "\\" + deviceName;

                // 需要获取importFolder中的*.db文件路径
                var dbFiles = Directory.GetFiles(importFolder, "*.db");
                if (dbFiles.Length == 0)
                {
                    return ApiResponse.Fail("导入的数据库文件不存在");
                }
                var dbPath = dbFiles[0];
                // 检查源文件是否存在
                if (!File.Exists(dbPath))
                {
                    return ApiResponse.Fail("导入的数据库文件不存在");
                }

                LogManager.Info($"开始导入设备数据库文件: {dbPath} -> {dbNewPath}");

                // 在文件复制前，强制关闭目标设备的数据库连接
                try
                {
                    LogManager.Info($"强制关闭设备 {deviceId} 的数据库连接以进行文件导入");
                    _deviceDbManager.ForceCloseDeviceDatabase(deviceId);
                }
                catch (Exception ex)
                {
                    LogManager.Warn($"关闭设备数据库连接时出现问题: {ex.Message}");
                }

                // 使用安全的文件复制方法
                bool copySuccess = _deviceDbManager.SafeFileCopy(dbPath, dbNewPath);
                
                if (!copySuccess)
                {
                    return ApiResponse.Fail("导入数据库文件失败，文件可能正在被使用");
                }

                LogManager.Info($"设备数据库文件导入成功: device_{deviceId}.db");
                return ApiResponse.Success("导入成功");
            }
            catch (Exception ex)
            {
                LogManager.Error($"导入设备数据库文件时出错: {ex.Message}", ex);
                return ApiResponse.Fail($"导入设备数据库文件失败: {ex.Message}");
            }
        }

        public void Dispose()
        {
            _deviceDbManager?.Dispose();
        }
    }
}

